ORG 0x7c00
;ORG 0x100


[SECTION .ld]
ALIGN 16
[BITS 16]
jmp LABEL_BEGIN
STR_FAILED_MSG: db "load kernel failed!", 0
STR_START_BOOT: db "start boot!", 0

disk_address_packet:	db	0x10		; [ 0] Packet size in bytes.
	db	0		; [ 1] Reserved, must be 0.
	db	1	    ; [ 2] Nr of blocks to transfer.
	db	0		; [ 3] Reserved, must be 0.
	dw	0		; [ 4] Addr of transfer - Offset
	dw	0x9000	; [ 6] buffer.          - Seg
	dd	0		; [ 8] LBA. Low  32-bits.
	dd	0		; [12] LBA. High 32-bits.

; read_sector
;----------------------------------------------------------------------------
; Entry:
;     - fields disk_address_packet should have been filled
;       before invoking the routine
; Exit:
;     - es:bx -> data read
; registers changed:
;     - //eax, ebx, dl, si, es
read_sector:
		push eax
		push ebx
		push edx
		push esi


		xor	ebx, ebx
		mov	ah, 0x42
		mov	dl, 0x80
		mov	si, disk_address_packet
		int	0x13
	    ;jc  failed2 ; retry        ; 如果读取错误 CF 会被置为 1, 这时就不停地读, 直到正确为止
	    jmp succ2
	failed2:
	    mov ah, 0x8C
	    mov al, 'E'
	    mov [gs:(80*0+1)*2], ax
	    jmp $
	succ2:
		pop esi
		pop edx
		pop ebx
		pop eax
		ret

LABEL_BEGIN:
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
    xor esi, esi
    xor edi, edi

	xor eax, eax
	mov ds, ax


    ; 清屏
	mov	ax, 0600h		; AH = 6,  AL = 0h
	mov	bx, 0700h		; 黑底白字(BL = 07h)
	mov	cx, 0			; 左上角: (0, 0)
	mov	dx, 0184fh		; 右下角: (80, 50)
	int	10h			; int 10h

    mov ax, 0xb800
    mov gs, ax
    mov ah, 0x0A
    mov al, 'B'
    mov [gs:(80*0+0)*2], ax

    ;xor esp, esp
    mov ax, 0x9000
    mov es, ax
    mov ax, 0x8000
    mov ss, ax
    mov sp, 0xFFFC

    mov si, 1 ;sect_no
    mov di, 0 ;to
    read_sect_test_loop:
    cmp si, 21 ;[1,20]
    jz read_sect_test_fin

    mov [disk_address_packet + 4], di ;to
    mov [disk_address_packet + 8], esi ;sect_no
    call read_sector ;注意:这里认为sect_no从0开始，取值区间为[0, 2879]

    add si, 1
    add di, 512
    jmp read_sect_test_loop

read_sect_test_fin:
    mov ah, 0x0A
    mov al, 'K'
    mov [gs:(80*0+1)*2], ax
	jmp ld_next

    ;show load err msg
    xor esi, esi
    xor edi, edi

    mov ah, 0x8C ;strength-red, blink
    mov esi, STR_FAILED_MSG
    mov edi, (80 * 0 + 0) * 2 ;屏幕第0行，0列
.show_msg_loop:
    mov al, [ds:esi]
    add esi, 1
    test al, al
    jz .show_msg_fin
    mov [gs:edi], ax
    add edi, 2
    jmp .show_msg_loop
.show_msg_fin:
    jmp $ ;err occur
    ;assert AH＝00H，AL＝传输的扇区数(8)

ld_next:
    jmp 0x9000:0   ;cs=0x9000   ip=0,见如下debug log
;<bochs:7> u/2 eip
;00007cea: (                    ): jmpf 0x9000:0000          ; ea00000090
;00007cef: (                    ): add byte ptr ds:[bx+si], al ; 0000
;<bochs:9> sreg
;cs:0x0000, ...
;ds:0x0000, ...
;<bochs:10> s
;Next at t=162963131
;(0) [0x000000090000] 9000:0000 (unk. ctxt): jmp .+721 (0x000902d4)    ; e9d102
;<bochs:11> sreg
;cs:0x9000, ...
;ds:0x0000, ...

    times (510 - ($ - $$)) db 0
    dw  0xaa55


; -------------------memory------------------------
;   phy-addr-range     len                content
; [0x9F000 - 0x9FFFF]  0x1000(4k)         unusable
; [0x90000 - 0x9F000)  0xF000(60k)        loader.bin
; [0x80000 - 0x90000)  0x10000(64k)       kernel.bin
; [0x30000 - 0x80000)  0x50000(320k)      kernel.prog
; [ 0x7e00 - 0x30000)  0x28200(160.5k)    free
; [ 0x7c00 - 0x7e00)   0x200(512B)        boot
; [  0x500 - 0x7c00)   0x7700(29.5k)      free
; [  0x400 - 0x500)    0x100(0.5k)        ROM BIOS Paramter
; [    0x0 - 0x7c00)   0x7c00(31k)        reserve

; -----------------floppy disk--------------------------------------------------------------
;      addr-range           len                 content        sector-range     sector-count
; [0x100000 - 0x168000)     0x68000(416k)       unusable       [2048, 2879]     832
; [ 0xf200  - 0x100000)     0xf0e00(963.5k)     kernel.bin     [121, 2047]      1927
; [  0x200  - 0xf200)       0xf000(60k)         loader.bin     [1, 120]         120
; [    0x0  - 0x200)        0x200(512B)         boot.img       [0, 0]           1

;----------------------avlable meminfo----------------------
;    range                              size
; [0x0 - 0x9F000)[0-636k)               0x9F000(636k)
; [0x100000-0x1FEF0000)[1M-511.9375M)   0x1FEF0000(510.9375M)

;------mem info------
;Addr-Low   Addr-High  Size-Low   Size-High  Type(1:usable)
;0x00000000 0x00000000 0x0009F000 0x00000000 0x00000001
;0x0009F000 0x00000000 0x00001000 0x00000000 0x00000002
;0x000E8000 0x00000000 0x00018000 0x00000000 0x00000002 (size=0x18000=98304=96k 1screen=80*25*2=4000=0xFA0 0x18000/0xFA0=24.567)
;0x00100000 0x00000000 0x1FEF0000 0x00000000 0x00000001
;0x1FFF0000 0x00000000 0x00010000 0x00000000 0x00000003
;0xFFFC0000 0x00000000 0x00040000 0x00000000 0x00000002
;0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
;Totol Mem Size:0x1FFF8000 Byte
;Max Avalable Mem Addr:0x1FFF0000


;debug flag  on screen 共25行，80列
;row/col   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16 ...未使用
;      0  00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f  0g
;      1  10  11  12  13  14  15  16  17  18  19  1a  1b  1c  1d  1e  1f  1g
;      2  TODO
;               事件
;  00:[B]		进入引导区代码
;  01:[E|K]		加载loader.bin失败	K:成功，E:失败
;  08:[L]		开始执行loader代码
;  09:[E|k]		加载kernel.bin   E:失败，k:成功
;  0a:[E|l]		取得内存容量信息   E:失败，l:成功
;  0b:[n]		准备进入保护模式
